package com.chenfan.process.entity.po;

import com.baomidou.mybatisplus.annotation.TableName;
import com.chenfan.ccp.entity.BaseEntity;
import com.chenfan.ccp.util.tool.UuidUtil;
import com.chenfan.infra.context.UserContextHolder;
import com.chenfan.infra.vo.UserVO;
import com.chenfan.process.enums.InstanceEnums;
import com.chenfan.process.enums.ProcessResultTypeEnums;
import com.chenfan.process.enums.SignTypeEnum;
import com.chenfan.process.vo.EntireProcessDetailVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.beans.BeanUtils;

import java.util.Date;

/**
 * @author K
 * @date 2021-04-26
 */
@EqualsAndHashCode(callSuper = true)
@Data
@TableName(value = "process_instance_approve_")
public class ProcessInstanceApprovePo extends BaseEntity<ProcessInstanceApprovePo> {

    public static final String APPROVAL_ID = "approval_id";
    public static final String STATUS = "status";
    public static final String APPROVAL_TEMPLATE_ID = "approval_template_id";
    public static final String APPROVAL_DETAIL_ID = "approval_detail_id";
    public static final String USER_ID = "user_id";
    public static final String REMARK = "remark";

    @ApiModelProperty("审批实例ID")
    private Long approvalId;

    @ApiModelProperty("审批模板ID")
    private Long approvalTemplateId;

    @ApiModelProperty("审批实例ID")
    private Long approvalDetailId;

    @ApiModelProperty("审批人类型 0-人员 1-上级 2-分组")
    private Integer type;

    @ApiModelProperty("审批人ID")
    private Long userId;

    @ApiModelProperty("人员详情")
    private String userDetail;

    @ApiModelProperty("审批人名称")
    private String userName;

    @ApiModelProperty("审批类型")
    private Integer approvalType;

    @ApiModelProperty("拥有者ID")
    private Long ownerId;

    @ApiModelProperty("状态 0-正常 1-处理完成 2-拒绝 3-驳回")
    private Integer status;

    @ApiModelProperty("备注")
    private String remark;

    private Long createBy;

    private String createName;

    private String updateName;

    private Long updateBy;

    private Boolean isSkip;

    /**
     * 转让备注
     */
    private String transferRemark;

    public void updateSelf() {
        setUpdateTime(new Date());
        UserVO userVo = UserContextHolder.getUserVo();
        if (userVo != null) {
            setUpdateBy(userVo.getUserId());
            setUpdateName(userVo.getRealName());
        }
    }

    public void setUp() {
        setCreateTime(new Date());
        UserVO userVo = UserContextHolder.getUserVo();
        if (userVo != null) {
            setCreateBy(userVo.getUserId());
            setCreateName(userVo.getRealName());
        }
    }

    public static ProcessInstanceApprovePo of(ApprovalPo approvalPo) {
        ProcessInstanceApprovePo of = of(approvalPo, SignTypeEnum.OR_SIGN.getCode());
        of.setUp();
        return of;
    }

    public static ProcessInstanceApprovePo of(ApprovalPo approvalPo, Integer approvalType) {
        ProcessInstanceApprovePo approvePo = new ProcessInstanceApprovePo();
        approvePo.setId(UuidUtil.generateId());
        approvePo.setApprovalId(approvalPo.getApprovalId());
        approvePo.setApprovalTemplateId(approvalPo.getApprovalTemplateId());
        approvePo.setApprovalType(approvalType);
        return approvePo;
    }

    public ProcessResultTypeEnums getProcessStatus() {
        if (InstanceEnums.NORMAL.getCode().equals(status)) {
            return ProcessResultTypeEnums.CREATED;
        }
        if (InstanceEnums.REVOKE.getCode().equals(status)) {
            return ProcessResultTypeEnums.REVOKE;
        }
        if (InstanceEnums.REFUSE.getCode().equals(status)) {
            return ProcessResultTypeEnums.REFUSED;
        }
        if (InstanceEnums.REJECTED.getCode().equals(status)) {
            return ProcessResultTypeEnums.REJECTED;
        }
        return ProcessResultTypeEnums.PASS;
    }

    public ProcessInstanceApprovePo cloneProcessInstance() {
        UserVO userVo = UserContextHolder.getUserVo();
        ProcessInstanceApprovePo processInstanceApprovePo = new ProcessInstanceApprovePo();
        BeanUtils.copyProperties(this, processInstanceApprovePo);
        processInstanceApprovePo.setId(UuidUtil.generateId());
        processInstanceApprovePo.setStatus(InstanceEnums.NORMAL.getCode());
        processInstanceApprovePo.setUpdateBy(null);
        processInstanceApprovePo.setUpdateTime(null);
        processInstanceApprovePo.setUpdateName(null);
        processInstanceApprovePo.setRemark(null);
        processInstanceApprovePo.setCreateBy(userVo.getUserId());
        processInstanceApprovePo.setCreateName(userVo.getRealName());
        processInstanceApprovePo.setCreateTime(new Date());
        return processInstanceApprovePo;
    }

    public boolean finish() {
        return !InstanceEnums.NORMAL.getCode().equals(this.getStatus());
    }

    public boolean normal() {
        return !finish();
    }

    public boolean revoke() {
        return InstanceEnums.REVOKE.getCode().equals(this.getStatus());
    }

    public boolean rejected() {
        return InstanceEnums.REJECTED.getCode().equals(this.getStatus());
    }

    public boolean isPass() {
        return InstanceEnums.PASS.getCode().equals(getStatus());
    }

    public String getSymbol() {
        return SignTypeEnum.COUNTER_SIGN.getCode().equals(approvalType) ? " & " : " | ";
    }

    public boolean counterSign() {
        return SignTypeEnum.COUNTER_SIGN.getCode().equals(approvalType);
    }

    public EntireProcessDetailVo.ProcessDetailInstance ofProcessInstance() {
        EntireProcessDetailVo.ProcessDetailInstance instance = new EntireProcessDetailVo.ProcessDetailInstance();
        instance.setCreateTime(getUpdateTime()!=null?getUpdateTime():getCreateTime());
        instance.setExecutorUserName(getUserName());
        instance.setRemark(getRemark());
        instance.setTransferRemark(getTransferRemark());
        ProcessResultTypeEnums processStatus = getProcessStatus();
        instance.setResultType(processStatus.getIndex());
        instance.setResultTypeValue(processStatus.getName());
        return instance;
    }

    public void reject(String remark) {
        setStatus(InstanceEnums.REJECTED.getCode());
        setRemark(remark);
        updateSelf();
    }

    public void pass() {
        setStatus(InstanceEnums.PASS.getCode());
        updateSelf();
    }

    public void pass(String remark) {
        setRemark(remark);
        pass();
    }

    public void refuse() {
        setStatus(InstanceEnums.REFUSE.getCode());
        updateSelf();
    }

    public void skippedPaas() {
        pass("系统自动执行, 原因: 与历史节点审批人相同");
    }
}
